Skip to content

Conversation

@philnik777
Copy link
Contributor

No description provided.

@philnik777 philnik777 requested a review from a team as a code owner October 8, 2025 12:17
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Oct 8, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 8, 2025

@llvm/pr-subscribers-libcxx

Author: Nikolas Klauser (philnik777)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/162459.diff

2 Files Affected:

  • (modified) libcxx/include/__config (+2-2)
  • (modified) libcxx/include/__type_traits/aligned_storage.h (+13-40)
diff --git a/libcxx/include/__config b/libcxx/include/__config
index b4c081dcdff1b..a77d40636838a 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -339,7 +339,7 @@ _LIBCPP_HARDENING_MODE_DEBUG
 
 #  ifndef _LIBCPP_CXX03_LANG
 
-#    define _LIBCPP_ALIGNOF(_Tp) alignof(_Tp)
+#    define _LIBCPP_ALIGNOF(...) alignof(__VA_ARGS__)
 #    define _ALIGNAS_TYPE(x) alignas(x)
 #    define _ALIGNAS(x) alignas(x)
 #    define _NOEXCEPT noexcept
@@ -348,7 +348,7 @@ _LIBCPP_HARDENING_MODE_DEBUG
 
 #  else
 
-#    define _LIBCPP_ALIGNOF(_Tp) _Alignof(_Tp)
+#    define _LIBCPP_ALIGNOF(...) _Alignof(__VA_ARGS__)
 #    define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
 #    define _ALIGNAS(x) __attribute__((__aligned__(x)))
 #    define nullptr __nullptr
diff --git a/libcxx/include/__type_traits/aligned_storage.h b/libcxx/include/__type_traits/aligned_storage.h
index 5c2208ae0c70a..33c0368d0c3c8 100644
--- a/libcxx/include/__type_traits/aligned_storage.h
+++ b/libcxx/include/__type_traits/aligned_storage.h
@@ -11,8 +11,6 @@
 
 #include <__config>
 #include <__cstddef/size_t.h>
-#include <__type_traits/integral_constant.h>
-#include <__type_traits/type_list.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -21,10 +19,10 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
-struct __align_type {
-  static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp);
-  typedef _Tp type;
-};
+struct _ALIGNAS(_LIBCPP_PREFERRED_ALIGNOF(_Tp)) _AlignedAsT {};
+
+template <class... _Args>
+struct __max_align_impl : _AlignedAsT<_Args>... {};
 
 struct __struct_double {
   long double __lx;
@@ -33,41 +31,16 @@ struct __struct_double4 {
   double __lx[4];
 };
 
-using __all_types _LIBCPP_NODEBUG =
-    __type_list<__align_type<unsigned char>,
-                __align_type<unsigned short>,
-                __align_type<unsigned int>,
-                __align_type<unsigned long>,
-                __align_type<unsigned long long>,
-                __align_type<double>,
-                __align_type<long double>,
-                __align_type<__struct_double>,
-                __align_type<__struct_double4>,
-                __align_type<int*> >;
-
-template <class _TL, size_t _Len>
-struct __find_max_align;
-
-template <class _Head, size_t _Len>
-struct __find_max_align<__type_list<_Head>, _Len> : public integral_constant<size_t, _Head::value> {};
-
-template <size_t _Len, size_t _A1, size_t _A2>
-struct __select_align {
-private:
-  static const size_t __min = _A2 < _A1 ? _A2 : _A1;
-  static const size_t __max = _A1 < _A2 ? _A2 : _A1;
-
-public:
-  static const size_t value = _Len < __max ? __min : __max;
-};
+inline const size_t __aligned_storage_max_align =
+    _LIBCPP_ALIGNOF(__max_align_impl<unsigned long long, double, long double, __struct_double, __struct_double4, int*>);
 
-template <class _Head, class... _Tail, size_t _Len>
-struct __find_max_align<__type_list<_Head, _Tail...>, _Len>
-    : public integral_constant<
-          size_t,
-          __select_align<_Len, _Head::value, __find_max_align<__type_list<_Tail...>, _Len>::value>::value> {};
+template <size_t _Len>
+inline const size_t __aligned_storage_alignment =
+    _Len > __aligned_storage_max_align
+        ? __aligned_storage_max_align
+        : size_t(1) << ((sizeof(size_t) * __CHAR_BIT__) - __builtin_clzg(_Len) - 1);
 
-template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
+template <size_t _Len, size_t _Align = __aligned_storage_alignment<_Len> >
 struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_NO_SPECIALIZATIONS aligned_storage {
   union _ALIGNAS(_Align) type {
     unsigned char __data[(_Len + _Align - 1) / _Align * _Align];
@@ -77,7 +50,7 @@ struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_NO_SPECIALIZATIONS aligned_storage {
 #if _LIBCPP_STD_VER >= 14
 
 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
-template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
+template <size_t _Len, size_t _Align = __aligned_storage_alignment<_Len> >
 using aligned_storage_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_storage<_Len, _Align>::type;
 _LIBCPP_SUPPRESS_DEPRECATED_POP
 

inline const size_t __aligned_storage_alignment =
_Len > __aligned_storage_max_align
? __aligned_storage_max_align
: size_t(1) << ((sizeof(size_t) * __CHAR_BIT__) - __builtin_clzg(_Len) - 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC, this computes the largest power of two that is less than or equal to the given _Len. So for example, for sizeof(T) == 3, we get an alignment of 2. For sizeof(T) == 4, we get 4.

I don't understand how that's correct. I would have thought that sizeof(T) implies that the alignment of T >= 4, doesn't it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you convinced me that this was the right thing since the size of a struct is always a multiple of its alignment.

inline const size_t __aligned_storage_alignment =
_Len > __aligned_storage_max_align
? __aligned_storage_max_align
: size_t(1) << ((sizeof(size_t) * __CHAR_BIT__) - __builtin_clzg(_Len) - 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you convinced me that this was the right thing since the size of a struct is always a multiple of its alignment.

@philnik777 philnik777 merged commit 43ca08d into llvm:main Nov 12, 2025
77 of 81 checks passed
@philnik777 philnik777 deleted the simplify_aligned_storage branch November 12, 2025 19:38
git-crd pushed a commit to git-crd/crd-llvm-project that referenced this pull request Nov 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants